package com.cloudinnov.logic.impl;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cloudinnov.dao.CapacityStatDao;
import com.cloudinnov.dao.ProductionLinesDao;
import com.cloudinnov.logic.CapacityStatLogic;
import com.cloudinnov.model.CapacityStat;
import com.cloudinnov.model.ProductionLines;
import com.cloudinnov.utils.PropertiesUtils;
import com.cloudinnov.websocket.ProductivityWebsocket;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * @author chengning
 * @date 2016年4月13日下午12:09:48
 * @email ningcheng@cloudinnov.com
 * @remark
 * @version 
 */
@Service
public class CapacityStatLogicImpl extends BaseLogicImpl<CapacityStat> implements CapacityStatLogic {

private static final Logger logger = Logger.getLogger(CapacityStatLogicImpl.class);
	
	private SimpleDateFormat sdf_YYYYMMDD = new SimpleDateFormat(":yyyyMMdd");

	@SuppressWarnings("unused")
	private SimpleDateFormat sdf_YYYYMMDDHH = new SimpleDateFormat(":yyyyMMddHH");
	
	
	public static final String QUERY_TYPE = "type";
	public static final int QUERY_TYPE_DETAIL = 1;
	public static final int QUERY_TYPE_DAY = 2;
	public static final int QUERY_TYPE_WEEK = 3;
	public static final int QUERY_TYPE_MONTH = 4;
	public static final int QUERY_TYPE_YEAR = 5;

	private static final String ENERGY_REDIS_SPILT = "_";
	private static final String CAPACITY_REDISKEY = "capacitystat:";
	private static final String CAPACITYCOUNT_REDISKEY = "capacitystatcount:";
	private static final String HISTORY_SPLITTER_LEVEL1 = ",";

	@Autowired
	private JedisPool redisPool;
	
	@Autowired
	private CapacityStatDao capacityStatDao;
	
	@Autowired
	private ProductionLinesDao productionLinesDao;
	
	@Override
	public List<CapacityStat> selectCapacityStatsByCondition(Map<String, Object> map) {
		List<CapacityStat> list = new ArrayList<CapacityStat>();
		if (map.get(QUERY_TYPE).equals(QUERY_TYPE_WEEK)) {
			list = capacityStatDao.selectCapacityStatsWeekByCondition(map);
		} else if (map.get(QUERY_TYPE).equals(QUERY_TYPE_MONTH)) {
			list = capacityStatDao.selectCapacityStatsMonthByCondition(map);
		} else if (map.get(QUERY_TYPE).equals(QUERY_TYPE_YEAR)) {
			list = capacityStatDao.selectCapacityStatsYearByCondition(map);
		} else if (map.get(QUERY_TYPE).equals(QUERY_TYPE_DAY)) {
			list = capacityStatDao.selectCapacityStatsDayByCondition(map);
		} 
		return list;
	}

	@Override
	public List<CapacityStat> selectCapacityStatsHourByCondition(Map<String, Object> map) {
		return capacityStatDao.selectCapacityStatsHourByCondition(map);
	}

	@Override
	public Page<CapacityStat> selectCapacityStatsDayByCondition(Map<String, Object> map) {
		PageHelper.startPage(Integer.parseInt(String.valueOf(map.get("index"))),
				Integer.parseInt(String.valueOf(map.get("size"))));
		return (Page<CapacityStat>) capacityStatDao.selectCapacityStatsDayByCondition(map);
	}

	@Override
	public Page<CapacityStat> selectCapacityStatsDetailByCondition(Map<String, Object> map) {
		PageHelper.startPage(Integer.parseInt(String.valueOf(map.get("index"))),
				Integer.parseInt(String.valueOf(map.get("size"))));
		return (Page<CapacityStat>) capacityStatDao.selectCapacityStatsDetailByCondition(map);
	}
	
	@Override
	public void energyPublishAll() {
		Calendar cal = Calendar.getInstance();
		Jedis redis = null;
		try {
			redis = redisPool.getResource();
			Map<String, Object> map = new HashMap<String, Object>();
			ObjectMapper mapper = new ObjectMapper();
			mapper.setSerializationInclusion(Include.NON_NULL);
			List<ProductionLines> result = null;
			redis.select(Integer.parseInt(PropertiesUtils.findPropertiesKey("redis.db.catastat")));
			Iterator<Map.Entry<String, ProductivityWebsocket>> entries = ProductivityWebsocket.webSocketMap.entrySet()
					.iterator();
			while (entries.hasNext()) {
				Map.Entry<String, ProductivityWebsocket> entry = entries.next();
				ProductionLines productionLine = new ProductionLines();
				productionLine.setCustomerCode(entry.getKey().split(ENERGY_REDIS_SPILT)[0]);
				productionLine.setLanguage(entry.getKey().split(ENERGY_REDIS_SPILT)[1]);
				List<ProductionLines> productionLines = productionLinesDao.selectProLineInfoByCode(productionLine);
				for (int i = 0; i < productionLines.size(); i++) {
					//String value = redis.lindex(CAPACITY_REDISKEY + productionLines.get(i).getCode(), 0);
					String value = redis.lindex(CAPACITYCOUNT_REDISKEY + productionLines.get(i).getCode() + sdf_YYYYMMDD.format(new Date()), 0);
					if (value != null) {
						cal.set(Calendar.DATE, cal.get(Calendar.DATE) - 1);
						cal.set(Calendar.HOUR_OF_DAY, 8);
						cal.set(Calendar.MINUTE, 0);
						cal.set(Calendar.SECOND, 0);
						String runTime = String.valueOf((System.currentTimeMillis() - cal.getTimeInMillis()) / 3600000);
						result = new ArrayList<ProductionLines>();
						productionLines.get(i).setStartTime(String.valueOf(cal.getTimeInMillis()));
						productionLines.get(i).setRunTime(runTime);
						productionLines.get(i).setDayProduction(value.split(HISTORY_SPLITTER_LEVEL1)[1]);
						//productionLines.get(i).setValue(Double.parseDouble(value.split(HISTORY_SPLITTER_LEVEL1)[1]));
						productionLines.get(i).setValue(Double.parseDouble(redis.lindex(CAPACITY_REDISKEY + productionLines.get(i).getCode(), 0).split(HISTORY_SPLITTER_LEVEL1)[1]));
						productionLines.get(i).setTime(value.split(HISTORY_SPLITTER_LEVEL1)[0] + "000");
						result.add(productionLines.get(i));
					}
				}
				if (result != null && result.size() > 0) {
					map.put("list", result);
					entry.getValue().sendMessage(mapper.writeValueAsString(map));
				}
			}
		} catch (JsonProcessingException e) {
			logger.error("产能推送服务异常\t" , e);
		} catch (IOException e) {
			logger.error("产能推送服务异常\t" , e);
		} finally {
			redisPool.returnResource(redis);
		}
	}

	@Override
	public void selectCapacityByProductLine(ProductionLines productionLine) {
		Calendar cal = Calendar.getInstance();
		Jedis redis = null;
		try {
			redis = redisPool.getResource();
			ObjectMapper mapper = new ObjectMapper();
			mapper.setSerializationInclusion(Include.NON_NULL);
			redis.select(Integer.parseInt(PropertiesUtils.findPropertiesKey("redis.db.catastat")));
			String value = redis.lindex(CAPACITYCOUNT_REDISKEY + productionLine.getCode()+sdf_YYYYMMDD.format(new Date()), 0);
			if (value == null) {
				productionLine.setStartTime(String.valueOf(System.currentTimeMillis()));
				productionLine.setRunTime("0");
				productionLine.setDayProduction("0");
				productionLine.setValue(0);
				productionLine.setTime("0");
			}else{
				Date date = new Date(Long.parseLong(value.split(HISTORY_SPLITTER_LEVEL1)[0]) * 1000);
				Calendar cal2 = Calendar.getInstance();
				cal2.set(Calendar.DATE, cal2.get(Calendar.DATE) + 1);
				//date.after(cal.getTime()) &&
				if( date.before(cal2.getTime())){
					cal.set(Calendar.DATE, cal.get(Calendar.DATE));
					cal.set(Calendar.HOUR_OF_DAY, 8);
					cal.set(Calendar.MINUTE, 54);
					cal.set(Calendar.SECOND, 0);
					String runTime = String.valueOf((System.currentTimeMillis() - cal.getTimeInMillis())/60000);
					productionLine.setStartTime(String.valueOf(cal.getTimeInMillis()));
					productionLine.setRunTime(runTime);
					productionLine.setDayProduction(value.split(HISTORY_SPLITTER_LEVEL1)[1]);
					productionLine.setValue(Double.parseDouble(redis.lindex(CAPACITY_REDISKEY + productionLine.getCode(), 0).split(HISTORY_SPLITTER_LEVEL1)[1]));
					productionLine.setTime(value.split(HISTORY_SPLITTER_LEVEL1)[0] + "000");
				}else{
					productionLine.setStartTime("0");
					productionLine.setRunTime("0");
					productionLine.setDayProduction("0");
					productionLine.setValue(Double.parseDouble(value.split(HISTORY_SPLITTER_LEVEL1)[1]));
					productionLine.setTime("0");
				}	
			}
		} finally {
			redisPool.returnResource(redis);
		}
	}
	
	@Override
	public List<ProductionLines> energyPublishByCustomer(String[] params) {
		if (params.length != 2) {
			return null;
		}
		Calendar cal = Calendar.getInstance();
		Jedis redis = null;
		List<ProductionLines> result = null;
		try {
			redis = redisPool.getResource();
			ObjectMapper mapper = new ObjectMapper();
			mapper.setSerializationInclusion(Include.NON_NULL);
			redis.select(Integer.parseInt(PropertiesUtils.findPropertiesKey("redis.db.catastat")));
			ProductionLines productionLine = new ProductionLines();
			productionLine.setCustomerCode(params[0]);
			productionLine.setLanguage(params[1]);
			List<ProductionLines> productionLines = productionLinesDao.selectProLineInfoByCode(productionLine);
			for (int i = 0; i < productionLines.size(); i++) {
				//String value = redis.lindex(CAPACITY_REDISKEY + productionLines.get(i).getCode(), 0);
				String value = redis.lindex(CAPACITYCOUNT_REDISKEY + productionLines.get(i).getCode() + sdf_YYYYMMDD.format(new Date()), 0);
				if (value == null) {
					result = new ArrayList<ProductionLines>();
					productionLines.get(i).setStartTime("0");
					productionLines.get(i).setRunTime("0");
					productionLines.get(i).setDayProduction("0");
					productionLines.get(i).setValue(0);
					productionLines.get(i).setTime("0");
					result.add(productionLines.get(i));
				}else{
					Date date = new Date(Long.parseLong(value.split(HISTORY_SPLITTER_LEVEL1)[0]) * 1000);
					Calendar cal2 = Calendar.getInstance();
					cal2.set(Calendar.HOUR_OF_DAY, 0); 
					cal2.set(Calendar.SECOND, 0); 
					cal2.set(Calendar.MINUTE, 0); 
					cal2.set(Calendar.MILLISECOND, 0); 
					
					Calendar cal3 = Calendar.getInstance();
					cal3.set(Calendar.HOUR_OF_DAY, 24); 
					cal3.set(Calendar.SECOND, 0); 
					cal3.set(Calendar.MINUTE, 0); 
					cal3.set(Calendar.MILLISECOND, 0); 
					if(date.after(cal2.getTime()) && date.before(cal3.getTime())){
						cal.set(Calendar.DATE, cal.get(Calendar.DATE) - 1);
						cal.set(Calendar.HOUR_OF_DAY, 8);
						cal.set(Calendar.MINUTE, 0);
						cal.set(Calendar.SECOND, 0);
						String runTime = String.valueOf((System.currentTimeMillis() - cal.getTimeInMillis()) / 3600000);
						result = new ArrayList<ProductionLines>();
						productionLines.get(i).setStartTime(String.valueOf(cal.getTimeInMillis()));
						productionLines.get(i).setRunTime(runTime);
						productionLines.get(i).setDayProduction(value.split(HISTORY_SPLITTER_LEVEL1)[1]);
						//productionLines.get(i).setValue(Double.parseDouble(value.split(HISTORY_SPLITTER_LEVEL1)[1]));
						productionLines.get(i).setValue(Double.parseDouble(value.split(HISTORY_SPLITTER_LEVEL1)[1]));
						productionLines.get(i).setTime(value.split(HISTORY_SPLITTER_LEVEL1)[0] + "000");
						result.add(productionLines.get(i));
					}else{
						result = new ArrayList<ProductionLines>();
						productionLines.get(i).setStartTime("0");
						productionLines.get(i).setRunTime("0");
						productionLines.get(i).setDayProduction("0");
						productionLines.get(i).setValue(Double.parseDouble(redis.lindex(CAPACITY_REDISKEY + productionLines.get(i).getCode(), 0).split(HISTORY_SPLITTER_LEVEL1)[1]));
						productionLines.get(i).setTime("0");
						result.add(productionLines.get(i));
					}									
				}
			}
		} finally {
			redisPool.returnResource(redis);
		}
		return result;
	}
}
